bitkeeper revision 1.1615.1.3 (429c99ecG3lpbZMR_ulpeFavnrTbcQ)
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Tue, 31 May 2005 17:07:56 +0000 (17:07 +0000)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Tue, 31 May 2005 17:07:56 +0000 (17:07 +0000)
Fix get_pte_flags/put_pte_flags macros. Limit 32-bit PAE to 44-bit
physical addresses (maximum PFN that will fit in a 32-bit word).
Signed-off-by: Keir Fraser <keir@xensource.com>
xen/include/asm-x86/x86_32/page-2level.h
xen/include/asm-x86/x86_32/page-3level.h
xen/include/asm-x86/x86_64/page.h

index 2c029b231701e14e9de3678a4c9261396981cdcf..732178280555a2ddd9879b9dbe304e1b8fedc393 100644 (file)
@@ -40,6 +40,13 @@ typedef l2_pgentry_t root_pgentry_t;
 #define is_guest_l1_slot(_s)    (1)
 #define is_guest_l2_slot(_t,_s) ((_s) < L2_PAGETABLE_FIRST_XEN_SLOT)
 
+/*
+ * PTE pfn and flags:
+ *  20-bit pfn   = (pte[31:12])
+ *  12-bit flags = (pte[11:0])
+ */
+
+/* Extract flags into 12-bit integer, or turn 12-bit flags into a pte mask. */
 #define get_pte_flags(x) ((int)(x) & 0xFFF)
 #define put_pte_flags(x) ((intpte_t)(x))
 
index d8cf21bfe591fe64edd65ba75c71639de7e9e1f0..a83f27f1f3f36777d68859c938d76a1decb6e03b 100644 (file)
 #define L3_PAGETABLE_ENTRIES    4
 #define ROOT_PAGETABLE_ENTRIES  L3_PAGETABLE_ENTRIES
 
-#define PADDR_BITS              52
+/*
+ * Architecturally, physical addresses may be up to 52 bits. However, the
+ * page-frame number (pfn) of a 52-bit address will not fit into a 32-bit
+ * word. Instead we treat bits 44-51 of a pte as flag bits which are never
+ * allowed to be set by a guest kernel. This 'limits' us to addressing 16TB
+ * of physical memory on a 32-bit PAE system.
+ */
+#define PADDR_BITS              44
 #define PADDR_MASK              ((1ULL << PADDR_BITS)-1)
 
 #ifndef __ASSEMBLY__
@@ -46,8 +53,15 @@ typedef l3_pgentry_t root_pgentry_t;
      ((_s) < (L2_PAGETABLE_FIRST_XEN_SLOT & (L2_PAGETABLE_ENTRIES-1))))
 #define is_guest_l3_slot(_s)    (1)
 
-#define get_pte_flags(x) ((int)((x) >> 40) | ((int)(x) & 0xFFF))
-#define put_pte_flags(x) ((((intpte_t)((x) & ~0xFFF)) << 40) | ((x) & 0xFFF))
+/*
+ * PTE pfn and flags:
+ *  32-bit pfn   = (pte[43:12])
+ *  32-bit flags = (pte[63:44],pte[11:0])
+ */
+
+/* Extract flags into 32-bit integer, or turn 32-bit flags into a pte mask. */
+#define get_pte_flags(x) (((int)((x) >> 32) & ~0xFFF) | ((int)(x) & 0xFFF))
+#define put_pte_flags(x) (((intpte_t)((x) & ~0xFFF) << 40) | ((x) & 0xFFF))
 
 #define L1_DISALLOW_MASK (0xFFFFF180U & ~_PAGE_NX) /* PAT/GLOBAL */
 #define L2_DISALLOW_MASK (0xFFFFF180U & ~_PAGE_NX) /* PSE/GLOBAL */
index 75bff5b6e96828e57ed31bb0b47921e10ec0a4b4..b27e9076fd33a762f1136b2a5b97e56452d019b0 100644 (file)
@@ -18,7 +18,7 @@
 
 #define __PAGE_OFFSET           (0xFFFF830000000000)
 
-/* These are page-table limitations. Current CPUs support only 40-bit phys. */
+/* These are architectural limits. Current CPUs support only 40-bit phys. */
 #define PADDR_BITS              52
 #define VADDR_BITS              48
 #define PADDR_MASK              ((1UL << PADDR_BITS)-1)
@@ -58,10 +58,18 @@ typedef l4_pgentry_t root_pgentry_t;
 #define root_create_phys          l4e_create_phys
 #define PGT_root_page_table PGT_l4_page_table
 
-#define get_pte_flags(x) ((int)((x) >> 40) | ((int)(x) & 0xFFF))
-#define put_pte_flags(x) ((((intpte_t)((x) & ~0xFFF)) << 40) | ((x) & 0xFFF))
+/*
+ * PTE pfn and flags:
+ *  40-bit pfn   = (pte[51:12])
+ *  24-bit flags = (pte[63:52],pte[11:0])
+ */
+
+/* Extract flags into 24-bit integer, or turn 24-bit flags into a pte mask. */
+#define get_pte_flags(x) (((int)((x) >> 40) & ~0xFFF) | ((int)(x) & 0xFFF))
+#define put_pte_flags(x) (((intpte_t)((x) & ~0xFFF) << 40) | ((x) & 0xFFF))
 
-#define _PAGE_NX                (cpu_has_nx ? (1U<<23) : 0U)
+/* Bit 23 of a 24-bit flag mask. This corresponds to bit 63 of a pte.*/
+#define _PAGE_NX (cpu_has_nx ? (1U<<23) : 0U)
 
 #define L1_DISALLOW_MASK (0xFFFFF180U & ~_PAGE_NX) /* PAT/GLOBAL */
 #define L2_DISALLOW_MASK (0xFFFFF180U & ~_PAGE_NX) /* PSE/GLOBAL */